﻿using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EWSEditor.CRM
{
    /// <summary>
    /// Class containing the delegate methods for each DiagnosticCheck
    /// Each Declared Method must confirm the following data on the DiagnosticCheck:
    /// 
    /// 1. Symptom
    /// 2. Cause
    /// 3. Resolution
    /// 4. TechnicalDetails
    /// 5. DiagnosticResult
    /// 6. TestFinished
    /// 7. OrgSettingUseCase  -- OrgDBOrgSetting Only
    /// 8. OrgSetting CurrentVal -- OrgDBOrgSetting Only
    /// 
    /// </summary>
    class DiagnosticCheckMethods
    {

        public DiagnosticCheckMethods()
        {

        }

        #region CHECK METHODS

        public static void CheckReceivingPostPonedUntilForACT(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "ACT synchronization appears slow or delayed.";

            DateTime date = new DateTime();
            date = DateTime.UtcNow;
            if ((((DateTime)CrmOrgMailboxCache.TargetMailbox["receivingpostponeduntilforact"]).Add(new TimeSpan(0, 0, 30, 0)) < date))
            {
                if ((DateTime)CrmOrgMailboxCache.TargetMailbox["postponemailboxprocessinguntil"] != DateTime.MaxValue.Date)
                {
                    diagCheck.Cause = "Server Side Synchronization may be experiencing issues with queueing the mailbox for work.";
                    diagCheck.Resolution = "Contact support for further assistance.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Error;
                }
                else if ((DateTime)CrmOrgMailboxCache.TargetMailbox["postponemailboxprocessinguntil"] == DateTime.MaxValue.Date && (((int)CrmOrgMailboxCache.TargetMailbox["processingstatecode"] == 1)))
                {
                    diagCheck.Cause = "Server Side Synchronization processing is taking longer than expected as the mailbox is still being processed by the last synchronization cycle. This can include both ACT and Incoming email sync cycles.";
                    diagCheck.Resolution = "You may be synchronizing many ACT folders, which can increase the time needed to process the mailbox. You can review your ACT synchronization folders by inspecting the LastFolderItemsSyncStates located in the Last Sync Details feature of this application. You can also contact support for further assistance.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Error;
                }
            }
            else
            {
                diagCheck.Cause = "N/A - ACT is processing as expected.";
                diagCheck.Resolution = "No action is needed.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
            }

            diagCheck.TestFinished = true;
            StringBuilder sb = new StringBuilder("mailbox.receivingpostponeduntilforact = ");
            diagCheck.TechnicalDetails = sb.Append(((DateTime)CrmOrgMailboxCache.TargetMailbox["receivingpostponeduntilforact"]).ToString()).ToString();
        }

        public static void CheckACTStatus(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "ACTs are not being processed by Server Side Synchronization.";

            if (((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["actdeliverymethod"]).Value == 2)
            {
                if ((((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["actstatus"]).Value == 2))
                {
                    diagCheck.Cause = "The mailbox encountered a failure during the test and enable process.";
                    diagCheck.Resolution = "Please see the Mailbox Alerts to determine why the mailbox failed to enable successfully for ACT synchronization.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Error;
                }

                else if ((((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["actstatus"]).Value == 0))
                {
                    diagCheck.Cause = "The mailbox has not been tested and enabled.";
                    diagCheck.Resolution = "A System Administrator needs to Test and Enable the mailbox.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Warning;
                    diagCheck.ShowDynamicHelp = true;
                    diagCheck.DynamicHelpUrl = "https://technet.microsoft.com/en-us/library/dn531109.aspx";
                }
                else
                {
                    diagCheck.Cause = "N/A";
                    diagCheck.Resolution = "No action is needed. Incoming Email Status is successful.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
                }
            }

            else
            {
                diagCheck.Cause = "N/A - The mailbox is not configured to synchronize ACTs with Exchange Server.";
                diagCheck.Resolution = "If you wish to use Server Side Sync to synchronize ACTs, follow the documentation in the Dynamic Help link below.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Information;
                diagCheck.ShowDynamicHelp = true;
                diagCheck.DynamicHelpUrl = "https://technet.microsoft.com/en-us/library/dn531109.aspx";
            }

            diagCheck.TestFinished = true;
        }

        public static void CheckSyncFilters(DiagnosticCheck diagCheck)
        {
            Dictionary<string, bool> filterDictionary = new Dictionary<string, bool>();
            filterDictionary.Add("contact", false);
            filterDictionary.Add("task", false);
            filterDictionary.Add("fax", false);
            filterDictionary.Add("appointment", false);
            filterDictionary.Add("recurringappointmentmaster", false);
            filterDictionary.Add("serviceappointment", false);
            filterDictionary.Add("phonecall", false);
            filterDictionary.Add("letter", false);

            EntityCollection filters = GetSyncFilters();

            foreach(Entity filter in filters.Entities)
            {
                string typecode = (string)filter["returnedtypecode"];

                switch (typecode)
                {
                    case "contact":
                        filterDictionary[typecode] = true;
                        break;

                    case "task":
                        filterDictionary[typecode] = true;
                        break;

                    case "fax":
                        filterDictionary[typecode] = true;
                        break;

                    case "appointment":
                        filterDictionary[typecode] = true;
                        break;

                    case "recurringappointmentmaster":
                        filterDictionary[typecode] = true;
                        break;

                    case "serviceappointment":
                        filterDictionary[typecode] = true;
                        break;

                    case "phonecall":
                        filterDictionary[typecode] = true;
                        break;

                    case "letter":
                        filterDictionary[typecode] = true;
                        break;
                }
            }

            StringBuilder sb = new StringBuilder("The following entities have their sync filter disabled: ");
            int filtersDisabled = 0;

            foreach (KeyValuePair<string,bool> keypair in filterDictionary)
            {
                if(keypair.Value == false)
                {
                    sb.Append(keypair.Key).Append(", ");
                    filtersDisabled = filtersDisabled + 1;
                }
            }

            diagCheck.Symptom = "Some entities do not synchronize to Exchange or Outlook.";
            diagCheck.Cause = "Synchronization filters are disabled or deleted.";

            if (filtersDisabled > 0)
            {
                diagCheck.Resolution = "Create or Enable the synchronization filters for the entities listed in the Technical Details section below. Your filters can be managed in the Personal Options section under the Synchronization tab.";
                diagCheck.TechnicalDetails = sb.ToString();
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Warning;
            }
            else
            {
                diagCheck.Resolution = "Synchronization filters for each entity type are enabled. If you wish to see the returned results of your synchronization filters, please use the Dynamics Sync Troubleshooter feature under the Dynamics 365 menu area of this application.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
            }

            diagCheck.TestFinished = true;

        }

        private static EntityCollection GetSyncFilters()
        {
            QueryByAttribute query = new QueryByAttribute("userquery");
            query.ColumnSet = new ColumnSet(new string[] { "fetchxml", "name", "returnedtypecode" });
            query.Attributes.AddRange("querytype");
            query.Values.AddRange(256);
            query.Attributes.AddRange("ownerid");
            query.Values.AddRange(CrmOrgMailboxCache.LoggedInSystemUser.Id);
            query.Attributes.AddRange("statecode");
            query.Values.AddRange(0);

            EntityCollection filters = CrmAuthInfoFactory.GetOrgProxy().RetrieveMultiple(query);
            return filters;
        }

        public static void CheckAutoCreateContacts(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "Unresolved senders on e-mail activity records are being created as Contacts in Dynamics 365";
            diagCheck.Resolution = "If this is not the desired functionality, toggle the setting in the user's personal options.";
            diagCheck.DiagnosticResult = DiagnosticCheckResult.Information;

            if ((int)CrmOrgMailboxCache.TargetUserSettings["autocreatecontactonpromote"] == 1)
            {
                diagCheck.Cause = "Automatically Create Contacts from unknown senders is enabled in the user's personal otpions under the E-mail tab.";
            }
            else
            {
                diagCheck.Cause = "N/A - Automatically Create Contacts from unknown senders is disabled in the user's personal otpions under the E-mail tab.";
            }

            StringBuilder sb = new StringBuilder("usersettings.autocreatecontactonpromote = ");
            diagCheck.TechnicalDetails = sb.Append((int)CrmOrgMailboxCache.TargetUserSettings["autocreatecontactonpromote"]).ToString();

            diagCheck.ShowDynamicHelp = true;
            diagCheck.DynamicHelpUrl = "https://www.microsoft.com/en-US/dynamics/crm-customer-center/set-personal-options.aspx";

            diagCheck.TestFinished = true;
        }

        public static void CheckReceivingPostPonedUntil(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "Incoming Email Processing appears slow or delayed.";

            DateTime date = new DateTime();
            date = DateTime.UtcNow;
            if ((((DateTime)CrmOrgMailboxCache.TargetMailbox["receivingpostponeduntil"]).Add(new TimeSpan(0, 0, 30, 0)) < date))
            {
                if ((DateTime)CrmOrgMailboxCache.TargetMailbox["postponemailboxprocessinguntil"] != DateTime.MaxValue.Date)
                {
                    diagCheck.Cause = "Server Side Synchronization may be experiencing issues with queueing the mailbox for work.";
                    diagCheck.Resolution = "Contact support for further assistance.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Error;
                }
                else if ((DateTime)CrmOrgMailboxCache.TargetMailbox["postponemailboxprocessinguntil"] == DateTime.MaxValue.Date && (((int)CrmOrgMailboxCache.TargetMailbox["processingstatecode"] == 1)))
                {
                    diagCheck.Cause = "Server Side Synchronization processing is taking longer than expected on the mailbox as it is still being processed by the last synchronization cycle. This can include both ACT and Incoming email sync cycles.";
                    diagCheck.Resolution = "Contact support for further assistance.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Error;
                }
            }
            else
            {
                diagCheck.Cause = "N/A - Incoming is processing as expected.";
                diagCheck.Resolution = "No action is needed.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
            }

            diagCheck.TestFinished = true;
            StringBuilder sb = new StringBuilder("mailbox.receivingpostponeduntil = ");
            diagCheck.TechnicalDetails = sb.Append(((DateTime)CrmOrgMailboxCache.TargetMailbox["receivingpostponeduntil"]).ToString()).ToString();
        }

        public static void CheckIncomingEmailStatus(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "Incoming Email is not being processed by Server Side Synchronization.";

            if (((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["incomingemaildeliverymethod"]).Value == 2)
            {
                if ((((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["incomingemailstatus"]).Value == 2))
                {
                    diagCheck.Cause = "The mailbox encountered a failure during the test and enable process.";
                    diagCheck.Resolution = "Please see the Mailbox Alerts to determine why the mailbox failed to enable successfully for incoming email.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Error;
                }

                else if ((((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["incomingemailstatus"]).Value == 0))
                {
                    diagCheck.Cause = "The mailbox has not been tested and enabled.";
                    diagCheck.Resolution = "A System Administrator needs to Test and Enable the mailbox.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Warning;
                }
                else
                {
                    diagCheck.Cause = "N/A";
                    diagCheck.Resolution = "No action is needed. Incoming Email Status is successful.";
                    diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
                }
            }
           
            else
            {
                diagCheck.Cause = "N/A - The mailbox is not configured to use Server Side Sync for Incoming Email.";
                diagCheck.Resolution = "If you wish to use Server Side Sync for incoming email, change the Incoming Email Delivery Method to Email Router or Server-Side Synchronization. You will then need to approve the email address and then Test and Enable the mailbox.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Information;
            }

            diagCheck.TestFinished = true;
        }

        public static void CheckEmailApproval(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "Email is not processed by Server Side Synchronization.";
            

            if (((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["emailrouteraccessapproval"]).Value != 1)
            {
                diagCheck.Cause = "The mailbox has not been approved and then Tested and Enabled by a System Administrator.";
                diagCheck.Resolution = "Follow the Help Url below for information on how to approve the mailbox.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Error;
            }
            else
            {
                diagCheck.Cause = "N/A";
                diagCheck.Resolution = "No action is needed. The mailbox is already approved.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
            }

            StringBuilder sb = new StringBuilder("mailbox.emailrtoueraccessapproval = ");
            diagCheck.TechnicalDetails = sb.Append(MetadataHelpers.GetOptionSetValueLabel("mailbox", "emailrouteraccessapproval", ((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["emailrouteraccessapproval"]).Value)).ToString();
            diagCheck.TestFinished = true;
        }

        public static void CheckAutoPromote(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "Some e-mails are not automatically promoted to Dynamics 365.";
            diagCheck.Cause = "Dynamics 365 users can choose which types of e-mails should be automatically promoted in their personal options. This can include All E-mail Messages, E-mail Messages in Response to Dynamics 365 Email, E-mail Messages from Accounts, Contacts, and Leads, and All E-mail Enabled Entities.";
            diagCheck.Resolution = "Review the personal options (Under the e-mail tab) to change the automatic promotion settings as needed. Please see the Technical Details below for the current setting.";
            diagCheck.DiagnosticResult = DiagnosticCheckResult.Information;

            if (CrmOrgMailboxCache.TargetMailboxIsQueue)
            {
                diagCheck.TechnicalDetails = MetadataHelpers.GetOptionSetValueLabel("queue", "incomingemailfilteringmethod", ((OptionSetValue)CrmOrgMailboxCache.Queue["incomingemailfilteringmethod"]).Value);
            }
            else
            {
                diagCheck.TechnicalDetails = MetadataHelpers.GetOptionSetValueLabel("usersettings", "incomingemailfilteringmethod", ((OptionSetValue)CrmOrgMailboxCache.TargetUserSettings["incomingemailfilteringmethod"]).Value);
            }

            diagCheck.ShowDynamicHelp = true;
            diagCheck.DynamicHelpUrl = "https://www.microsoft.com/en-US/dynamics/crm-customer-center/set-an-option-to-automatically-track-incoming-outlook-email-in-dynamics-365-for-outlook.aspx";
            diagCheck.TestFinished = true;
        }

        public static void CheckIgnoreInternalEmail(DiagnosticCheck diagCheck)
        {
            if ((bool)CrmOrgMailboxCache.Organization["ignoreinternalemail"])
            {
                diagCheck.Symptom = "Emails between two users are not tracked as two seperate e-mail activity records.";
                diagCheck.Cause = "Ignore Internal Email is turned on in the System Settings.";
                diagCheck.TechnicalDetails = "Organization.IgnoreInternalEmails = true";
            }
            else
            {
                diagCheck.Symptom = "Emails between two users are being tracked as two seperate e-mail activity records.";
                diagCheck.Cause = "Ignore Internal Email is turned off in the System Settings.";
                diagCheck.TechnicalDetails = "Organization.IgnoreInternalEmails = false";
            }

            diagCheck.Resolution = "If you wish to change this behavior, you can toggle the Ignore Internal Email checkbox in the system settings. You can also click on the Fix It button below to perform the change automatically.";
            diagCheck.DiagnosticResult = DiagnosticCheckResult.Information;
            diagCheck.ShowDynamicHelp = true;
            diagCheck.DynamicHelpUrl = "https://www.microsoft.com/en-US/dynamics/crm-customer-center/system-settings-dialog-box-email-tab.aspx";
            diagCheck.TestFinished = true;
        }

        public static void CheckEmailCorrelation(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "Some emails in response to Dynamics 365 email may not be automatically tracking as expected.";
            

            if (!(bool)CrmOrgMailboxCache.Organization["emailcorrelationenabled"])
            {
                diagCheck.Resolution = "Turn on Email Correlation in the System Settings. This setting improves the detection logic of email responses from known Dynamics 365 activities using In-Reply-To and ConversationIndex properties. To change this setting, click on the Fix It button below.";
                diagCheck.TechnicalDetails = "Organization.emailcorrelationenabled = false";
                diagCheck.Cause = "Email Correlation has been disabled in the System Settings.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Warning;
                diagCheck.TechnicalDetails = "organization.emailcorrelationenabled = false";
            }
            else
            {
                diagCheck.Cause = "N/A";
                diagCheck.Resolution = "Email Correlation is already Enabled. No action is needed.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
                diagCheck.TechnicalDetails = "organization.emailcorrelationenabled = true";
            }

            diagCheck.ShowDynamicHelp = true;
            diagCheck.DynamicHelpUrl = "https://www.microsoft.com/en-US/dynamics/crm-customer-center/system-settings-dialog-box-email-tab.aspx";
            diagCheck.TestFinished = true;
        }

        public static void CheckCorrelationMethods(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "Some emails in response to Dynamics 365 email may not be automatically tracking as expected.";
            

            if (((int)CrmOrgMailboxCache.Organization["maximumtrackingnumber"] == 0) && (!CrmOrgMailboxCache.Organization.Contains("enablesmartmatching")))
            {
                diagCheck.Resolution = "Turn on either Tracking Token or Smart Matching to help improve e-mail correlation detection logic. These settings can be changed under the Email tab in System Settings.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Warning;
                diagCheck.Cause = "Tracking Token and Smart Matching Settings have been disabled in the System Settings.";
                diagCheck.TechnicalDetails = "Organization.MaximumTrackingNumber = 0 & Organizaiton.EnableSmartMatching = null";
            }
            else
            {
                diagCheck.Cause = "N/A";
                diagCheck.Resolution = "Tracking Token and/or Smart Matching is already enabled. No action is needed.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
            }

            diagCheck.ShowDynamicHelp = true;
            diagCheck.DynamicHelpUrl = "https://technet.microsoft.com/library/hh699705.aspx";
            diagCheck.TestFinished = true;
        }

        public static void CheckConnectionChannelForACT(DiagnosticCheck diagCheck)
        {
            diagCheck.Symptom = "ACT Synchronization may experience long delays in mailbox processing.";

            if ((((OptionSetValue)CrmOrgMailboxCache.Organization["emailconnectionchannel"]).Value == 0) && (((OptionSetValue)CrmOrgMailboxCache.TargetMailbox["actdeliverymethod"]).Value == 2))
            {
                diagCheck.Resolution = "If any mailboxes participate in ACT Synchronization via Server Side Sync, the Email Connection Channel must be set to Server Side Synchronization to avoid potential issues.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Error;
                diagCheck.Cause = "The Email Connection Channel in the System Settings is set to E-mail Router.";
                diagCheck.TechnicalDetails = "Organization.emailconnectionchannel = 0 & Mailbox.actdeliverymethod = Server Side Sync";
            }
            else
            {
                diagCheck.Cause = "N/A";
                diagCheck.Resolution = "Email Connection Channel is configured correctly. No action is needed.";
                diagCheck.DiagnosticResult = DiagnosticCheckResult.Success;
            }

            diagCheck.TestFinished = true;
        }

        public static void CheckOrgDbOrgSetting(DiagnosticCheck diagCheck)
        {

            diagCheck.OrgSettingCurrentVal = SetOrgSettingValue(diagCheck);
            diagCheck.ShowDynamicHelp = true;
            diagCheck.DynamicHelpUrl = "https://support.microsoft.com/en-us/help/2691237/orgdborgsettings-tool-for-microsoft-dynamics-crm";

            switch (diagCheck.CheckName)
            {
                case "AllowPromoteDuplicates":
                    diagCheck.OrgSettingUseCase = "When this setting is enabled, duplicate e-mail activity records can be promoted to Dynamics 365 based on their MessageId attribute.";
                    break;

                case "AutoCreateContactOnPromote":
                    diagCheck.OrgSettingUseCase = "When this setting is disabled, users will not automatically create contacts for unknown senders when promoting emails to Dynamics 365. When disabled, this setting supercedes user preferences.";
                    break;

                case "DisableSmartMatching":
                    diagCheck.OrgSettingUseCase = "When this setting is disabled, Dynamics 365 will no longer utilize Smart Matching algorithms to correlate responses to Dynamics 365 e-mail for promotion candidates.";
                    break;

                case "DoNotIgnoreInternalEmailToQueues":
                    diagCheck.OrgSettingUseCase = "When this setting is enabled, emails from Dynamics 365 users to queues are promoted to Dynamics 365.";
                    break;

                case "EnableReLinkingToExistingCRMRecord":
                    diagCheck.OrgSettingUseCase = "When this setting is enabled, users can re-track contact records to Dynamics 365."; //Needs better detail.
                    break;

                case "OutlookSyncDataSubscriptionClientsBatchSize":
                    diagCheck.OrgSettingUseCase = "This setting determines how many items will be selected, per entity and action type, for synchronization by a synchronization client, during a single polling interval.";
                    break;

            }
            diagCheck.DiagnosticResult = DiagnosticCheckResult.Information;
            diagCheck.TestFinished = true;
        }

        private static string SetOrgSettingValue(DiagnosticCheck diagCheck)
        {
            string value = CrmOrgMailboxCache.OrgDBOrgSettings[diagCheck.CheckName];
            return value;
        }
        #endregion

        #region FIX IT METHODS

        public static void ChangeIgnoreInternalEmail(DiagnosticCheck diagCheck)
        {

        }


        /// <summary>
        /// Updates the specified CRM Setting.
        /// Needs to be called from a Try/Catch so that any exceptions can be displayed for debugging purposes.
        /// </summary>
        /// <param name="Setting">The string value represents the entity name, while the CRMUpdateKeyPair contains the attribute name and value stored as object</param>
        private static void UpdateSetting(Dictionary<string, CRMUpdateKeyPair> Setting)
        {
            OrganizationServiceProxy orgProxy = CrmAuthInfoFactory.GetOrgProxy();

            foreach(KeyValuePair<string, CRMUpdateKeyPair> keypair in Setting)
            {
                PerformUpdate(keypair, orgProxy);
            }
            
        }

        private static void PerformUpdate(KeyValuePair<string, CRMUpdateKeyPair> keyPair, OrganizationServiceProxy orgProxy)
        {
            Entity entityForUpdate = new Entity(keyPair.Key);

            var valueasstring = keyPair.Value.Value as string;

            if (valueasstring != null)
            {
                entityForUpdate[keyPair.Value.Attribute] = valueasstring;
                orgProxy.Update(entityForUpdate);
            }

            var valueasentityreference = keyPair.Value.Value as EntityReference;

            if (valueasentityreference != null)
            {
                entityForUpdate[keyPair.Value.Attribute] = valueasentityreference;
                orgProxy.Update(entityForUpdate);
            }

            if (keyPair.Value.Value.GetType() == typeof(int))
            {
                entityForUpdate[keyPair.Value.Attribute] = (int)keyPair.Value.Value;
                orgProxy.Update(entityForUpdate);
            }

            if (keyPair.Value.Value.GetType() == typeof(DateTime))
            {
                entityForUpdate[keyPair.Value.Attribute] = (DateTime)keyPair.Value.Value;
                orgProxy.Update(entityForUpdate);
            }

            if (keyPair.Value.Value.GetType() == typeof(Guid))
            {
                entityForUpdate[keyPair.Value.Attribute] = (Guid)keyPair.Value.Value;
                orgProxy.Update(entityForUpdate);
            }

            if (keyPair.Value.Value.GetType() == typeof(bool))
            {
                entityForUpdate[keyPair.Value.Attribute] = (bool)keyPair.Value.Value;
                orgProxy.Update(entityForUpdate);
            }

            if (keyPair.Value.Value.GetType() == typeof(OptionSetValue))
            {
                entityForUpdate[keyPair.Value.Attribute] = (OptionSetValue)keyPair.Value.Value; //Is this supposed to be int?
                orgProxy.Update(entityForUpdate);
            }

            //If the passed keyPair could not be casted and updated, we need to throw an error.
            throw new Exception("Unable to update setting: " + keyPair.Value.Attribute);
        }

        #endregion

    }
}
